package enron;

import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

import jade.core.Agent;
//import jade.core.AID;
import jade.lang.acl.ACLMessage;
import jade.proto.ContractNetInitiator;
import jade.util.leap.Iterator;

public class AdjustSupplyBehaviour extends ContractNetInitiator {
	private static final long serialVersionUID = 5187664385927553141L;
	private int supplierCount;
	
	
	public AdjustSupplyBehaviour(Agent a, ACLMessage cfp, int supplierCount) {
		super(a, cfp);
		//System.out.println("Sending CFPs to:");
		Iterator recievers = cfp.getAllReceiver();
		while(recievers.hasNext()) {
			//System.out.println("     " + ((AID)recievers.next()).getLocalName());
		}

		this.supplierCount = supplierCount;
	}

	@SuppressWarnings("rawtypes")
	protected void handlePropose(ACLMessage propose, Vector v) {
		//System.out.println("Grid Adjust: (" + myAgent.getAID().getLocalName()+") "+propose.getSender().getLocalName()+" cost function: "+propose.getContent()+".");
	}

	protected void handleRefuse(ACLMessage refuse) {
		//System.out.println("Grid Adjust: (" + myAgent.getAID().getLocalName()+") "+refuse.getSender().getName()+" refused.");
		supplierCount--;
		if(supplierCount == 0) {
			((EnergyGrid)myAgent).isFixingFrequency = false;
		} else {
			//System.out.println("Still waiting for responses: " + supplierCount);
		}
	}

	protected void handleFailure(ACLMessage failure) {
		((EnergyGrid)myAgent).isFixingFrequency = false;
		if (failure.getSender().equals(myAgent.getAMS())) {
			// FAILURE notification from the JADE runtime: the receiver
			// does not exist
			//System.out.println("Grid Adjust: " + "Responder does not exist");
		}
		else {
			//System.out.println("Grid Adjust: (" + myAgent.getAID().getLocalName()+") Agent "+failure.getSender().getName()+" failed");
		}
	}

	@Override
	protected void handleAllResponses(@SuppressWarnings("rawtypes") Vector rawResponses, @SuppressWarnings("rawtypes") Vector rawAcceptances) {
		@SuppressWarnings("unchecked")
		Vector<ACLMessage> acceptances = rawAcceptances;
		@SuppressWarnings("unchecked")
		Vector<ACLMessage> responses = rawResponses;
		
		ACLMessage reply;

		//System.out.println(responses);
		
		Vector<ACLMessage> refused = new Vector<ACLMessage>();
		for(ACLMessage msg : responses) {
			if(msg.getPerformative() == ACLMessage.REFUSE) {
				refused.add(msg);
			}
		}
		
		responses.removeAll(refused);
		
		if(responses.size() >0){
			Collections.sort(responses, new Comparator<ACLMessage>(){

				@Override
				public int compare(ACLMessage msg1, ACLMessage msg2) {
					int returnVal = 0;
					if(msg1.getContent() == null) {
						returnVal = -1;
					} else if(msg2.getContent() == null) {
						returnVal = 1;
					} else {
						returnVal = Double.compare(Double.parseDouble(msg1.getContent()), Double.parseDouble(msg2.getContent()));
					}

					return returnVal;
				}

			});
			
			reply = responses.firstElement().createReply();
			reply.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
			//System.out.println("Grid Adjust: " + myAgent.getLocalName() + " - " + responses.firstElement().getSender().getLocalName() + " Accepting turn-down cost of" +  responses.firstElement().getContent() + ".");
			acceptances.add(reply);

			responses.remove(responses.size() - 1);

			for(ACLMessage msg : responses) {
				if (msg.getPerformative() == ACLMessage.PROPOSE) {
					reply = msg.createReply();
					reply.setPerformative(ACLMessage.REJECT_PROPOSAL);
					acceptances.addElement(reply);
					//System.out.println("Grid Adjust: " + myAgent.getLocalName() + " - " + msg.getSender().getLocalName() + " Rejecting turn-down cost of" + msg.getContent() + ".");
				}
			}
		}	
	}

	/*
		// Accept the proposal of the best proposer
		if (accept != null) {
			System.out.println("Grid Adjust: " + myAgent.getAID().getLocalName()+": Accepting $"+bestProposal+"/kWh from "+bestProposer.getLocalName() + ".");
			accept.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
		}*/						

	protected void handleInform(ACLMessage inform) {
		//System.out.println("Grid adjusted by " + inform.getSender().getLocalName()+".");
		((EnergyGrid)myAgent).isFixingFrequency = false;
	}
}
